/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.gs.practice.thread.util;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.JPanel;

/**
 *
 * @author Sabuj
 */
public class ArrayView extends JPanel implements PropertyChangeListener{
    private static final Color EMPTY_CELL = Color.LIGHT_GRAY;
    private static final Color FILLED_CELL = Color.BLUE;
    private static final Color CELL_SEP = Color.MAGENTA;
    private static final int SEP_WIDTH = 1;
    private static final int MIN_CELL_WIDTH = 2;
    private static final int MAX_CELL_WIDTH = 16;
    
    private final CircularArrayQueue<Integer> bufferQueue;
    private final Map<Integer, Cell> indexCellMap ;
    
    private Graphics2D currentGraphics ;
    
    public ArrayView(final CircularArrayQueue<Integer> bufferQueue) {
        this.bufferQueue = bufferQueue;
        setBackground(Color.BLACK);
        indexCellMap = new LinkedHashMap<>(bufferQueue.capacity());
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        currentGraphics = g2;
        int w = getSize().width - 20;
        int h = getSize().height - 5;
        int startX = getLocation().x + 10;
        int startY = getLocation().y + 5;
        System.out.println(startX + ", " + startY);
        System.out.println(w + ", " + h);
        int capacity = bufferQueue.capacity();
        
        
        g2.setColor(CELL_SEP);
        g2.drawRect(startX, getLocation().y, w, h);
        
        
        int tw = w - (2 * SEP_WIDTH);
        int cellHeight = h - 7;
        
        int cellWidth = Math.max(MIN_CELL_WIDTH, 
                (tw - ((capacity-2) * SEP_WIDTH)) / capacity);
        
        int cellStartX = startX + 1;
        for(int i=0; i<capacity; i++){
            Point cellLocation = new Point(
                    cellStartX,
                    startY);
            Dimension cellSize = new Dimension(cellWidth, cellHeight);
            Cell cell = new Cell(
                    cellLocation, cellSize
            );
            if(i >= bufferQueue.getFront() && i <= bufferQueue.getRare()){
                cell.setFillColor(FILLED_CELL);
            } else {
                cell.setFillColor(EMPTY_CELL);
            }
            System.out.println("i = " + i + "\t" + cell);
            indexCellMap.put(i, cell);
            drawCell(g2, cell);
            cellStartX += cellWidth;
            if(i >= 0 && i < capacity-1){
                cellStartX += SEP_WIDTH + 1;
                drawSeparator(g2, cell.location.x+cell.size.width,
                        getLocation().y, h);
            }
        }
        
    }

    private void drawCell(Graphics2D g2, Cell cell) {
        g2.setColor(cell.fillColor);
        g2.fillRect(cell.location.x, cell.location.y, 
                cell.size.width, cell.size.height);
    }

    private void drawSeparator(Graphics2D g2, int x, int y, int h) {
        g2.setColor(CELL_SEP);
        g2.fillRect(x, y, SEP_WIDTH, h);
    }

    @Override
    public void repaint() {
        super.repaint();
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        
    }
    
    private class Cell{
        private final Point location;
        private final Dimension size;
        private Color fillColor;

        public Cell(Point location, Dimension size) {
            this.location = location;
            this.size = size;
        }

        public void setFillColor(Color fillColor) {
            this.fillColor = fillColor;
        }

        @Override
        public String toString() {
            return "Cell{" + location.x + "," + location.y + " : " 
                    + size.width + "," + size.height + '}';
        }
        
        
    }
    
}
